package com.springlearn.springsourcecode.chap1;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


/**
 * @author wtcode
 * @Description
 * @date 2025/3/26 - 15:30
 */
public class TestBeanFactory {

    public static void main(String[] args) {
        // 创建bean 容器
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        // 生成bean定义的抽象类
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition();
        // 将bean注册进容器
        beanFactory.registerBeanDefinition("config",beanDefinition);


        // 给BeanFactory添加一些常用的后处理器
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

        // BeanFactory后处理器补充了一些Bean的定义
        beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().stream().forEach(beanFactoryPostProcessor -> {
            beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
        });

        // Bean后处理器，针对bean的生命周期的各个阶段提供扩展，例如@Autowired @Resource
        beanFactory.getBeansOfType(BeanPostProcessor.class).values().forEach(beanFactory::addBeanPostProcessor);


        for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }

        beanFactory.preInstantiateSingletons();

        System.out.println("<----------------------------------------->");
        System.out.println(beanFactory.getBean(Bean1.class).getBean2());

    }

    @Configuration
    static class Config{

        @Bean
        public Bean1 bean1(){
            return new Bean1();
        }

        @Bean
        public Bean2 bean2(){
            return new Bean2();
        }

    }


    static class Bean1{
        private static final Logger logger = LoggerFactory.getLogger(Bean1.class);

        public Bean1(){
            logger.debug("构造bean1");
        }

        @Autowired
        private Bean2 bean2;

        public Bean2 getBean2(){
            return bean2;
        }

    }


    static class Bean2{
        private static final Logger logger = LoggerFactory.getLogger(Bean2.class);
        public Bean2(){
            logger.debug("构造bean2");
        }
    }
}
